<!DOCTYPE html>
<html lang="zh-CN" dir="ltr">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>11.7 JSON转Dart Model类 | 落光的Pro博客</title>
    <meta name="description" content="Vite & Vue powered static site generator.">
    <link rel="preload stylesheet" href="./assets/style.4b0df91d.css" as="style">
    
    <script type="module" src="./assets/app.0acbd3fd.js"></script>
    <link rel="preload" href="./assets/inter-roman-latin.2ed14f66.woff2" as="font" type="font/woff2" crossorigin="">
    <link rel="modulepreload" href="./assets/chunks/framework.eaf25f5b.js">
    <link rel="modulepreload" href="./assets/chunks/theme.ce44a0e6.js">
    <link rel="modulepreload" href="./assets/largeFrontEnd_flutter_chapter11_json_model.md.c84d2ccf.lean.js">
    <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-1919c326><!--[--><!--]--><!--[--><span tabindex="-1" data-v-0f60ec36></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-0f60ec36> Skip to content </a><!--]--><!----><header class="VPNav" data-v-1919c326 data-v-7e5bc4a5><div class="VPNavBar has-sidebar" data-v-7e5bc4a5 data-v-a0fd61f4><div class="container" data-v-a0fd61f4><div class="title" data-v-a0fd61f4><div class="VPNavBarTitle has-sidebar" data-v-a0fd61f4 data-v-86d1bed8><a class="title" href="./" data-v-86d1bed8><!--[--><!--]--><!--[--><img class="VPImage logo" src="./icon-radius.png" alt data-v-8426fc1a><!--]--><!--[-->落光的Pro博客<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-a0fd61f4><div class="curtain" data-v-a0fd61f4></div><div class="content-body" data-v-a0fd61f4><!--[--><!--]--><div class="VPNavBarSearch search" style="--vp-meta-key:&#39;Meta&#39;;" data-v-a0fd61f4><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg class="DocSearch-Search-Icon" width="20" height="20" viewBox="0 0 20 20" aria-label="search icon"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-a0fd61f4 data-v-7f418b0f><span id="main-nav-aria-label" class="visually-hidden" data-v-7f418b0f>Main Navigation</span><!--[--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-7f418b0f data-v-9c007e85><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-9c007e85><span class="text" data-v-9c007e85><!----><span data-v-9c007e85>大前端</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-9c007e85><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-9c007e85><div class="VPMenu" data-v-9c007e85 data-v-e7ea1737><div class="items" data-v-e7ea1737><!--[--><!--[--><div class="VPMenuLink" data-v-e7ea1737 data-v-43f1e123><a class="VPLink link" href="./largeFrontEnd/webFrontEnd/md/01.html" data-v-43f1e123><!--[-->Web前端<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-e7ea1737 data-v-43f1e123><a class="VPLink link" href="./largeFrontEnd/uniapp/" data-v-43f1e123><!--[-->Uni-app<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-e7ea1737 data-v-43f1e123><a class="VPLink link" href="./largeFrontEnd/weChatMiniProgram/" data-v-43f1e123><!--[-->微信小程序<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-e7ea1737 data-v-43f1e123><a class="VPLink link" href="./largeFrontEnd/electron/" data-v-43f1e123><!--[-->Electron<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-e7ea1737 data-v-43f1e123><a class="VPLink link" href="./largeFrontEnd/flutter/" data-v-43f1e123><!--[-->Flutter<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-e7ea1737 data-v-43f1e123><a class="VPLink link" href="./largeFrontEnd/interview/01.html" data-v-43f1e123><!--[-->前端面试题<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="./backEnd/" tabindex="0" data-v-7f418b0f data-v-42ef59de><!--[--><span data-v-42ef59de>后端</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="./linux/" tabindex="0" data-v-7f418b0f data-v-42ef59de><!--[--><span data-v-42ef59de>Linux</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="./myTeam/" tabindex="0" data-v-7f418b0f data-v-42ef59de><!--[--><span data-v-42ef59de>我的团队</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-a0fd61f4 data-v-f6a63727><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-f6a63727 data-v-ce54a7d1 data-v-b1685198><span class="check" data-v-b1685198><span class="icon" data-v-b1685198><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-ce54a7d1><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-ce54a7d1><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-a0fd61f4 data-v-0394ad82 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://gitee.com/luoguangguang" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="..." aria-label="cool link" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Dribbble</title><path d="M12...6.38z"/></svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-a0fd61f4 data-v-40855f84 data-v-9c007e85><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-9c007e85><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-9c007e85><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-9c007e85><div class="VPMenu" data-v-9c007e85 data-v-e7ea1737><!----><!--[--><!--[--><!----><div class="group" data-v-40855f84><div class="item appearance" data-v-40855f84><p class="label" data-v-40855f84>Appearance</p><div class="appearance-action" data-v-40855f84><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-40855f84 data-v-ce54a7d1 data-v-b1685198><span class="check" data-v-b1685198><span class="icon" data-v-b1685198><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-ce54a7d1><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-ce54a7d1><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><div class="group" data-v-40855f84><div class="item social-links" data-v-40855f84><div class="VPSocialLinks social-links-list" data-v-40855f84 data-v-7bc22406><!--[--><a class="VPSocialLink no-icon" href="https://gitee.com/luoguangguang" aria-label="github" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><a class="VPSocialLink no-icon" href="..." aria-label="cool link" target="_blank" rel="noopener" data-v-7bc22406 data-v-f80f8133><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Dribbble</title><path d="M12...6.38z"/></svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-a0fd61f4 data-v-e5dd9c1c><span class="container" data-v-e5dd9c1c><span class="top" data-v-e5dd9c1c></span><span class="middle" data-v-e5dd9c1c></span><span class="bottom" data-v-e5dd9c1c></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav reached-top" data-v-1919c326 data-v-79c8c1df><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-79c8c1df><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-79c8c1df><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-79c8c1df>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-79c8c1df data-v-1c15a60a><button data-v-1c15a60a>Return to top</button><!----></div></div><aside class="VPSidebar" data-v-1919c326 data-v-b00e2fdd><div class="curtain" data-v-b00e2fdd></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-b00e2fdd><span class="visually-hidden" id="sidebar-aria-label" data-v-b00e2fdd> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-b00e2fdd><section class="VPSidebarItem level-0 collapsible" data-v-b00e2fdd data-v-e31bd47b><div class="item" role="button" tabindex="0" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><h2 class="text" data-v-e31bd47b>Flutter入门到实战</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-e31bd47b><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-e31bd47b><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-e31bd47b><!--[--><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter1/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第一章 初识Flutter</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter2/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第二章 简介</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter3/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第三章 基础组件</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter4/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第四章 布局类组件</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter5/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第五章 容器类Widget</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter6/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第六章 可滚动组件</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter7/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第七章 功能型Widget简介</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter8/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第八章 事件处理与通知</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter9/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第九章 动画</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter10/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第十章 自定义组件</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter11/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第十一章 文件操作</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter12/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第十二章 Flutter 扩展</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter13/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第十三章 多语言</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-e31bd47b data-v-e31bd47b><div class="item" data-v-e31bd47b><div class="indicator" data-v-e31bd47b></div><a class="VPLink link link" href="./largeFrontEnd/flutter/chapter14/index.html" data-v-e31bd47b><!--[--><p class="text" data-v-e31bd47b>第十四章 高级进阶</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-1919c326 data-v-669faec9><div class="VPDoc has-sidebar has-aside" data-v-669faec9 data-v-6b87e69f><!--[--><!--]--><div class="container" data-v-6b87e69f><div class="aside" data-v-6b87e69f><div class="aside-curtain" data-v-6b87e69f></div><div class="aside-container" data-v-6b87e69f><div class="aside-content" data-v-6b87e69f><div class="VPDocAside" data-v-6b87e69f data-v-3f215769><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" role="navigation" data-v-3f215769 data-v-6ae8e080><div class="content" data-v-6ae8e080><div class="outline-marker" data-v-6ae8e080></div><div class="outline-title" role="heading" data-v-6ae8e080>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-6ae8e080><span class="visually-hidden" id="doc-outline-aria-label" data-v-6ae8e080> Table of Contents for current page </span><ul class="root" data-v-6ae8e080 data-v-d0ee3533><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-3f215769></div><!--[--><!--]--><div class="VPDocAsideCarbonAds" data-v-3f215769><div class="VPCarbonAds" data-v-2e1efd59></div></div><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-6b87e69f><div class="content-container" data-v-6b87e69f><!--[--><!--]--><!----><main class="main" data-v-6b87e69f><div style="position:relative;" class="vp-doc _largeFrontEnd_flutter_chapter11_json_model" data-v-6b87e69f><div><h1 id="_11-7-json转dart-model类" tabindex="-1">11.7 JSON转Dart Model类 <a class="header-anchor" href="#_11-7-json转dart-model类" aria-label="Permalink to &quot;11.7 JSON转Dart Model类&quot;">​</a></h1><h2 id="_11-7-1-json转dart类" tabindex="-1">11.7.1 JSON转Dart类 <a class="header-anchor" href="#_11-7-1-json转dart类" aria-label="Permalink to &quot;11.7.1 JSON转Dart类&quot;">​</a></h2><h3 id="_1-简介" tabindex="-1">1. 简介 <a class="header-anchor" href="#_1-简介" aria-label="Permalink to &quot;1. 简介&quot;">​</a></h3><p>在实战中，后台接口往往会返回一些结构化数据，如 JSON、XML 等，如之前我们请求 Github API 的示例，它返回的数据就是 JSON 格式的字符串，为了方便我们在代码中操作 JSON，我们先将 JSON 格式的字符串转为 Dart 对象，这个可以通过 <code>dart:convert</code> 中内置的 JSON 解码器<code>json.decode()</code>来实现，该方法可以根据 JSON 字符串具体内容将其转为 List 或 Map，这样我们就可以通过他们来查找所需的值，如：</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">//一个JSON格式的用户列表字符串</span></span>
<span class="line"><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> jsonStr</span><span style="color:#F97583;">=</span><span style="color:#9ECBFF;">&#39;[{&quot;name&quot;:&quot;Jack&quot;},{&quot;name&quot;:&quot;Rose&quot;}]&#39;</span><span style="color:#E1E4E8;">;`</span></span>
<span class="line"><span style="color:#6A737D;">//将JSON字符串转为Dart对象(此处是List)</span></span>
<span class="line"><span style="color:#79B8FF;">List</span><span style="color:#E1E4E8;"> items</span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;">json.</span><span style="color:#B392F0;">decode</span><span style="color:#E1E4E8;">(jsonStr);</span></span>
<span class="line"><span style="color:#6A737D;">//输出第一个用户的姓名</span></span>
<span class="line"><span style="color:#B392F0;">print</span><span style="color:#E1E4E8;">(items[</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">][</span><span style="color:#9ECBFF;">&quot;name&quot;</span><span style="color:#E1E4E8;">]);</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">//一个JSON格式的用户列表字符串</span></span>
<span class="line"><span style="color:#005CC5;">String</span><span style="color:#24292E;"> jsonStr</span><span style="color:#D73A49;">=</span><span style="color:#032F62;">&#39;[{&quot;name&quot;:&quot;Jack&quot;},{&quot;name&quot;:&quot;Rose&quot;}]&#39;</span><span style="color:#24292E;">;`</span></span>
<span class="line"><span style="color:#6A737D;">//将JSON字符串转为Dart对象(此处是List)</span></span>
<span class="line"><span style="color:#005CC5;">List</span><span style="color:#24292E;"> items</span><span style="color:#D73A49;">=</span><span style="color:#24292E;">json.</span><span style="color:#6F42C1;">decode</span><span style="color:#24292E;">(jsonStr);</span></span>
<span class="line"><span style="color:#6A737D;">//输出第一个用户的姓名</span></span>
<span class="line"><span style="color:#6F42C1;">print</span><span style="color:#24292E;">(items[</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">][</span><span style="color:#032F62;">&quot;name&quot;</span><span style="color:#24292E;">]);</span></span></code></pre></div><p>通过<code>json.decode()</code> 将 JSON 字符串转为 List/Map 的方法比较简单，它没有外部依赖或其他的设置，对于小项目很方便。但当项目变大时，这种手动编写序列化逻辑可能变得难以管理且容易出错，例如有如下JSON：</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#E1E4E8;">{</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;John Smith&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;email&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;john@example.com&quot;</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;">{</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;John Smith&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;email&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;john@example.com&quot;</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>我们可以通过调用<code>json.decode</code>方法来解码 JSON ，使用 JSON 字符串作为参数:</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; user </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> json.</span><span style="color:#B392F0;">decode</span><span style="color:#E1E4E8;">(json);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0;">print</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;Howdy, ${</span><span style="color:#79B8FF;">user</span><span style="color:#9ECBFF;">[&#39;name&#39;]}!&#39;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#B392F0;">print</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;We sent the verification link to ${</span><span style="color:#79B8FF;">user</span><span style="color:#9ECBFF;">[&#39;email&#39;]}.&#39;</span><span style="color:#E1E4E8;">);</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; user </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> json.</span><span style="color:#6F42C1;">decode</span><span style="color:#24292E;">(json);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6F42C1;">print</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;Howdy, ${</span><span style="color:#005CC5;">user</span><span style="color:#032F62;">[&#39;name&#39;]}!&#39;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#6F42C1;">print</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;We sent the verification link to ${</span><span style="color:#005CC5;">user</span><span style="color:#032F62;">[&#39;email&#39;]}.&#39;</span><span style="color:#24292E;">);</span></span></code></pre></div><p>由于<code>json.decode()</code>仅返回一个<code>Map&lt;String, dynamic&gt;</code>，这意味着直到运行时我们才知道值的类型。 通过这种方法，我们失去了大部分静态类型语言特性：类型安全、自动补全和最重要的编译时异常。这样一来，我们的代码可能会变得非常容易出错。例如，当我们访问<code>name</code>或<code>email</code>字段时，我们输入的很快，导致字段名打错了。但由于这个 JSON 在 map 结构中，所以编译器不知道这个错误的字段名，所以编译时不会报错。</p><p>其实，这个问题在很多平台上都会遇到，而也早就有了好的解决方法即“Json Model化”，具体做法就是，通过预定义一些与 Json 结构对应的 Model 类，然后在请求到数据后再动态根据数据创建出 Model 类的实例。这样一来，在开发阶段我们使用的是 Model 类的实例，而不再是 Map/List，这样访问内部属性时就不会发生拼写错误。例如，我们可以通过引入一个简单的模型类（Model class）来解决前面提到的问题，我们称之为<code>User</code>。在User类内部，我们有：</p><ul><li>一个<code>User.fromJson</code> 构造函数, 用于从一个 map 构造出一个 <code>User</code>实例 map 结构。</li><li>一个<code>toJson</code> 方法, 将 <code>User</code> 实例转化为一个 map。</li></ul><p>这样，调用代码现在可以具有类型安全、自动补全字段（name和email）以及编译时异常。如果我们将拼写错误字段视为<code>int</code>类型而不是<code>String</code>， 那么我们的代码就不会通过编译，而不是在运行时崩溃。</p><p><strong>user.dart</strong></p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">final</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> name;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">final</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> email;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.name, </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.email);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">fromJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; json)</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">:</span><span style="color:#E1E4E8;"> name </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> json[</span><span style="color:#9ECBFF;">&#39;name&#39;</span><span style="color:#E1E4E8;">],</span></span>
<span class="line"><span style="color:#E1E4E8;">        email </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> json[</span><span style="color:#9ECBFF;">&#39;email&#39;</span><span style="color:#E1E4E8;">];</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; </span><span style="color:#B392F0;">toJson</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">=&gt;</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#F97583;">&gt;</span><span style="color:#E1E4E8;">{</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#9ECBFF;">&#39;name&#39;</span><span style="color:#F97583;">:</span><span style="color:#E1E4E8;"> name,</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#9ECBFF;">&#39;email&#39;</span><span style="color:#F97583;">:</span><span style="color:#E1E4E8;"> email,</span></span>
<span class="line"><span style="color:#E1E4E8;">    };</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">User</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">final</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> name;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">final</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> email;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.name, </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.email);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">fromJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; json)</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">:</span><span style="color:#24292E;"> name </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> json[</span><span style="color:#032F62;">&#39;name&#39;</span><span style="color:#24292E;">],</span></span>
<span class="line"><span style="color:#24292E;">        email </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> json[</span><span style="color:#032F62;">&#39;email&#39;</span><span style="color:#24292E;">];</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; </span><span style="color:#6F42C1;">toJson</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">=&gt;</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#D73A49;">&gt;</span><span style="color:#24292E;">{</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#032F62;">&#39;name&#39;</span><span style="color:#D73A49;">:</span><span style="color:#24292E;"> name,</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#032F62;">&#39;email&#39;</span><span style="color:#D73A49;">:</span><span style="color:#24292E;"> email,</span></span>
<span class="line"><span style="color:#24292E;">    };</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>现在，序列化逻辑移到了模型本身内部。采用这种新方法，我们可以非常容易地反序列化user.</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;"> userMap </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> json.</span><span style="color:#B392F0;">decode</span><span style="color:#E1E4E8;">(json);</span></span>
<span class="line"><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> user </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">fromJson</span><span style="color:#E1E4E8;">(userMap);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0;">print</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;Howdy, ${</span><span style="color:#79B8FF;">user</span><span style="color:#9ECBFF;">.</span><span style="color:#79B8FF;">name</span><span style="color:#9ECBFF;">}!&#39;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#B392F0;">print</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;We sent the verification link to ${</span><span style="color:#79B8FF;">user</span><span style="color:#9ECBFF;">.</span><span style="color:#79B8FF;">email</span><span style="color:#9ECBFF;">}.&#39;</span><span style="color:#E1E4E8;">);</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#005CC5;">Map</span><span style="color:#24292E;"> userMap </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> json.</span><span style="color:#6F42C1;">decode</span><span style="color:#24292E;">(json);</span></span>
<span class="line"><span style="color:#D73A49;">var</span><span style="color:#24292E;"> user </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">fromJson</span><span style="color:#24292E;">(userMap);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6F42C1;">print</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;Howdy, ${</span><span style="color:#005CC5;">user</span><span style="color:#032F62;">.</span><span style="color:#005CC5;">name</span><span style="color:#032F62;">}!&#39;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#6F42C1;">print</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;We sent the verification link to ${</span><span style="color:#005CC5;">user</span><span style="color:#032F62;">.</span><span style="color:#005CC5;">email</span><span style="color:#032F62;">}.&#39;</span><span style="color:#24292E;">);</span></span></code></pre></div><p>要序列化一个user，我们只是将该<code>User</code>对象传递给该<code>json.encode</code>方法。我们不需要手动调用<code>toJson</code>这个方法，因为`JSON.encode内部会自动调用。</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> json </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> json.</span><span style="color:#B392F0;">encode</span><span style="color:#E1E4E8;">(user);</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#005CC5;">String</span><span style="color:#24292E;"> json </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> json.</span><span style="color:#6F42C1;">encode</span><span style="color:#24292E;">(user);</span></span></code></pre></div><p>这样，调用代码就不用担心JSON序列化了，但是，Model类还是必须的。在实践中，<code>User.fromJson</code>和<code>User.toJson</code>方法都需要单元测试到位，以验证正确的行为。</p><p>另外，实际场景中，JSON对象很少会这么简单，嵌套的JSON对象并不罕见，如果有什么能为我们自动处理JSON序列化，那将会非常好。幸运的是，有！</p><h3 id="_2-自动生成model" tabindex="-1">2. 自动生成Model <a class="header-anchor" href="#_2-自动生成model" aria-label="Permalink to &quot;2. 自动生成Model&quot;">​</a></h3><p>尽管还有其他库可用，但在本书中，我们介绍一下官方推荐的<a href="https://pub.dartlang.org/packages/json_serializable" target="_blank" rel="noreferrer">json_serializable package</a>包。 它是一个自动化的源代码生成器，可以在开发阶段为我们生成 JSON 序列化模板，这样一来，由于序列化代码不再由我们手写和维护，我们将运行时产生 JSON 序列化异常的风险降至最低。</p><h4 id="_1-在项目中设置-json-serializable" tabindex="-1">1）在项目中设置 json_serializable <a class="header-anchor" href="#_1-在项目中设置-json-serializable" aria-label="Permalink to &quot;1）在项目中设置 json_serializable&quot;">​</a></h4><p>要包含<code>json_serializable</code>到我们的项目中，我们需要一个常规和两个<strong>开发依赖</strong>项。简而言之，<strong>开发依赖项</strong>是不包含在我们的应用程序源代码中的依赖项，它是开发过程中的一些辅助工具、脚本，和 node 中的开发依赖项相似。</p><p><strong>pubspec.yaml</strong></p><div class="language-yaml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">yaml</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#85E89D;">dependencies</span><span style="color:#E1E4E8;">:</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#85E89D;">json_annotation</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&lt;最新版本&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#85E89D;">dev_dependencies</span><span style="color:#E1E4E8;">:</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#85E89D;">build_runner</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&lt;最新版本&gt;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#85E89D;">json_serializable</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&lt;最新版本&gt;</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#22863A;">dependencies</span><span style="color:#24292E;">:</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#22863A;">json_annotation</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&lt;最新版本&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#22863A;">dev_dependencies</span><span style="color:#24292E;">:</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#22863A;">build_runner</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&lt;最新版本&gt;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#22863A;">json_serializable</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&lt;最新版本&gt;</span></span></code></pre></div><p>在您的项目根文件夹中运行 <code>flutter packages get</code> (或者在编辑器中点击 “Packages Get”) 以在项目中使用这些新的依赖项.</p><h4 id="_2-以json-serializable的方式创建model类" tabindex="-1">2）以json_serializable的方式创建model类 <a class="header-anchor" href="#_2-以json-serializable的方式创建model类" aria-label="Permalink to &quot;2）以json_serializable的方式创建model类&quot;">​</a></h4><p>让我们看看如何将我们的<code>User</code>类转换为一个<code>json_serializable</code>。为了简单起见，我们使用前面示例中的简化JSON model。</p><p><strong>user.dart</strong></p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;">// user.g.dart 将在我们运行生成命令后自动生成</span></span>
<span class="line"><span style="color:#F97583;">part</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;user.g.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;">///这个标注是告诉生成器，这个类是需要生成Model类的</span></span>
<span class="line"><span style="color:#F97583;">@JsonSerializable</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">{</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.name, </span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">.email);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> name;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> email;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#6A737D;">//不同的类使用不同的mixin即可</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">factory</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">fromJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; json) </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">_$UserFromJson</span><span style="color:#E1E4E8;">(json);</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; </span><span style="color:#B392F0;">toJson</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">_$UserToJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">);  </span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;">// user.g.dart 将在我们运行生成命令后自动生成</span></span>
<span class="line"><span style="color:#D73A49;">part</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;user.g.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;">///这个标注是告诉生成器，这个类是需要生成Model类的</span></span>
<span class="line"><span style="color:#D73A49;">@JsonSerializable</span><span style="color:#24292E;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">{</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.name, </span><span style="color:#005CC5;">this</span><span style="color:#24292E;">.email);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> name;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> email;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#6A737D;">//不同的类使用不同的mixin即可</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">factory</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">fromJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; json) </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">_$UserFromJson</span><span style="color:#24292E;">(json);</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; </span><span style="color:#6F42C1;">toJson</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">_$UserToJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">);  </span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>有了上面的设置，源码生成器将生成用于序列化<code>name</code>和<code>email</code>字段的JSON代码。</p><p>如果需要，自定义命名策略也很容易。例如，如果我们正在使用的API返回带有_snake_case_的对象，但我们想在我们的模型中使用_lowerCamelCase_， 那么我们可以使用@JsonKey标注：</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;">//显式关联JSON字段名与Model属性的对应关系 </span></span>
<span class="line"><span style="color:#F97583;">@JsonKey</span><span style="color:#E1E4E8;">(name</span><span style="color:#F97583;">:</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;registration_date_millis&#39;</span><span style="color:#E1E4E8;">)</span></span>
<span class="line"><span style="color:#F97583;">final</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">int</span><span style="color:#E1E4E8;"> registrationDateMillis;</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;">//显式关联JSON字段名与Model属性的对应关系 </span></span>
<span class="line"><span style="color:#D73A49;">@JsonKey</span><span style="color:#24292E;">(name</span><span style="color:#D73A49;">:</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;registration_date_millis&#39;</span><span style="color:#24292E;">)</span></span>
<span class="line"><span style="color:#D73A49;">final</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">int</span><span style="color:#24292E;"> registrationDateMillis;</span></span></code></pre></div><h4 id="_3-运行代码生成程序" tabindex="-1">3）运行代码生成程序 <a class="header-anchor" href="#_3-运行代码生成程序" aria-label="Permalink to &quot;3）运行代码生成程序&quot;">​</a></h4><p><code>json_serializable</code>第一次创建类时，您会看到与图11-4类似的错误。</p><p><img src="/assets/11-4.23e7d68a.png" alt="图11-4"></p><p>这些错误是完全正常的，这是因为Model类的生成代码还不存在。为了解决这个问题，我们必须运行代码生成器来为我们生成序列化模板。有两种运行代码生成器的方法：</p><ul><li>一次性生成</li></ul><p>通过在我们的项目根目录下运行:</p><div class="language-shell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">shell</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">flutter</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">packages</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">pub</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">run</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">build_runner</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">build</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">flutter</span><span style="color:#24292E;"> </span><span style="color:#032F62;">packages</span><span style="color:#24292E;"> </span><span style="color:#032F62;">pub</span><span style="color:#24292E;"> </span><span style="color:#032F62;">run</span><span style="color:#24292E;"> </span><span style="color:#032F62;">build_runner</span><span style="color:#24292E;"> </span><span style="color:#032F62;">build</span></span></code></pre></div><p>这触发了一次性构建，我们可以在需要时为我们的 Model 生成 json 序列化代码，它通过我们的源文件，找出需要生成 Model 类的源文件（包含@JsonSerializable 标注的）来生成对应的 .g.dart 文件。一个好的建议是将所有 Model 类放在一个单独的目录下，然后在该目录下执行命令。</p><p>虽然这非常方便，但如果我们不需要每次在Model类中进行更改时都要手动运行构建命令的话会更好。</p><ul><li>持续生成</li></ul><p>使用_watcher_可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化，并在需要时自动构建必要的文件，我们可以通过<code>flutter packages pub run build_runner watch</code>在项目根目录下运行来启动_watcher_。只需启动一次观察器，然后它就会在后台运行，这是安全的。</p><h2 id="_11-7-2-一句命令实现json转dart类" tabindex="-1">11.7.2 一句命令实现JSON转dart类 <a class="header-anchor" href="#_11-7-2-一句命令实现json转dart类" aria-label="Permalink to &quot;11.7.2 一句命令实现JSON转dart类&quot;">​</a></h2><h3 id="_1-实现" tabindex="-1">1. 实现 <a class="header-anchor" href="#_1-实现" aria-label="Permalink to &quot;1. 实现&quot;">​</a></h3><p>上面的方法有一个最大的问题就是要为每一个json写模板，这是比较枯燥的。如果有一个工具可以直接根据JSON文本生成模板，那我们就能彻底解放双手了。笔者自己用dart实现了一个脚本，它可以自动生成模板，并直接将JSON转为Model类，下面我们看看怎么做：</p><ol><li><p>定义一个&quot;模板的模板&quot;，名为&quot;template.dart&quot;：</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#F97583;">%</span><span style="color:#E1E4E8;">t</span></span>
<span class="line"><span style="color:#F97583;">part</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;%s.g.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">@JsonSerializable</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">%</span><span style="color:#E1E4E8;">s {</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">%</span><span style="color:#B392F0;">s</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">%</span><span style="color:#E1E4E8;">s</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">factory</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">%</span><span style="color:#E1E4E8;">s.</span><span style="color:#B392F0;">fromJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; json) </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> _$</span><span style="color:#F97583;">%</span><span style="color:#B392F0;">sFromJson</span><span style="color:#E1E4E8;">(json);</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; </span><span style="color:#B392F0;">toJson</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> _$</span><span style="color:#F97583;">%</span><span style="color:#B392F0;">sToJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#D73A49;">%</span><span style="color:#24292E;">t</span></span>
<span class="line"><span style="color:#D73A49;">part</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;%s.g.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">@JsonSerializable</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">%</span><span style="color:#24292E;">s {</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">%</span><span style="color:#6F42C1;">s</span><span style="color:#24292E;">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">%</span><span style="color:#24292E;">s</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">factory</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">%</span><span style="color:#24292E;">s.</span><span style="color:#6F42C1;">fromJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; json) </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> _$</span><span style="color:#D73A49;">%</span><span style="color:#6F42C1;">sFromJson</span><span style="color:#24292E;">(json);</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; </span><span style="color:#6F42C1;">toJson</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> _$</span><span style="color:#D73A49;">%</span><span style="color:#6F42C1;">sToJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>模板中的“%t”、“%s”为占位符，将在脚本运行时动态被替换为合适的导入头和类名。</p></li><li><p>写一个自动生成模板的脚本(mo.dart)，它可以根据指定的JSON目录，遍历生成模板，在生成时我们定义一些规则：</p><ul><li>如果JSON文件名以下划线“_”开始，则忽略此JSON文件。</li><li>复杂的JSON对象往往会出现嵌套，我们可以通过一个特殊标志来手动指定嵌套的对象（后面举例）。</li></ul><p>脚本我们通过Dart来写，源码如下：</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;dart:convert&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;dart:io&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;package:path/path.dart&#39;</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">as</span><span style="color:#E1E4E8;"> path;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">TAG</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;</span><span style="color:#79B8FF;">\$</span><span style="color:#9ECBFF;">&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">SRC</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;./json&quot;</span><span style="color:#E1E4E8;">; </span><span style="color:#6A737D;">//JSON 目录</span></span>
<span class="line"><span style="color:#F97583;">const</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">DIST</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;lib/models/&quot;</span><span style="color:#E1E4E8;">; </span><span style="color:#6A737D;">//输出model目录</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">void</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">walk</span><span style="color:#E1E4E8;">() {</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#6A737D;">//遍历JSON目录生成模板</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> src </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">Directory</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">SRC</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> list </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> src.</span><span style="color:#B392F0;">listSync</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> template </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">File</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;./template.dart&quot;</span><span style="color:#E1E4E8;">).</span><span style="color:#B392F0;">readAsStringSync</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">File</span><span style="color:#E1E4E8;"> file;</span></span>
<span class="line"><span style="color:#E1E4E8;">  list.</span><span style="color:#B392F0;">forEach</span><span style="color:#E1E4E8;">((f) {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (</span><span style="color:#79B8FF;">FileSystemEntity</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">isFileSync</span><span style="color:#E1E4E8;">(f.path)) {</span></span>
<span class="line"><span style="color:#E1E4E8;">      file </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">File</span><span style="color:#E1E4E8;">(f.path);</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> paths </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> path.</span><span style="color:#B392F0;">basename</span><span style="color:#E1E4E8;">(f.path).</span><span style="color:#B392F0;">split</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;.&quot;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> name </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> paths.first;</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (paths.last.</span><span style="color:#B392F0;">toLowerCase</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">!=</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;json&quot;</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">||</span><span style="color:#E1E4E8;"> name.</span><span style="color:#B392F0;">startsWith</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;_&quot;</span><span style="color:#E1E4E8;">)) </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (name.</span><span style="color:#B392F0;">startsWith</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;_&quot;</span><span style="color:#E1E4E8;">)) </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#6A737D;">//下面生成模板</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> map </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> json.</span><span style="color:#B392F0;">decode</span><span style="color:#E1E4E8;">(file.</span><span style="color:#B392F0;">readAsStringSync</span><span style="color:#E1E4E8;">());</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#6A737D;">//为了避免重复导入相同的包，我们用Set来保存生成的import语句。</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">set</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">Set</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">&gt;();</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#79B8FF;">StringBuffer</span><span style="color:#E1E4E8;"> attrs </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">StringBuffer</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"><span style="color:#E1E4E8;">      (map </span><span style="color:#F97583;">as</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt;).</span><span style="color:#B392F0;">forEach</span><span style="color:#E1E4E8;">((key, v) {</span></span>
<span class="line"><span style="color:#E1E4E8;">        </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (key.</span><span style="color:#B392F0;">startsWith</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;_&quot;</span><span style="color:#E1E4E8;">)) </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">        </span><span style="color:#6A737D;">//所有字段都定义为可空</span></span>
<span class="line"><span style="color:#E1E4E8;">        attrs.</span><span style="color:#B392F0;">write</span><span style="color:#E1E4E8;">(</span><span style="color:#B392F0;">getType</span><span style="color:#E1E4E8;">(v, </span><span style="color:#F97583;">set</span><span style="color:#E1E4E8;">, name)</span><span style="color:#F97583;">+</span><span style="color:#9ECBFF;">&quot;?&quot;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">        attrs.</span><span style="color:#B392F0;">write</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot; &quot;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">        attrs.</span><span style="color:#B392F0;">write</span><span style="color:#E1E4E8;">(key);</span></span>
<span class="line"><span style="color:#E1E4E8;">        attrs.</span><span style="color:#B392F0;">writeln</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;;&quot;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">        attrs.</span><span style="color:#B392F0;">write</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;    &quot;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">      });</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> className </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> name[</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">].</span><span style="color:#B392F0;">toUpperCase</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">+</span><span style="color:#E1E4E8;"> name.</span><span style="color:#B392F0;">substring</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> dist </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">format</span><span style="color:#E1E4E8;">(template, [</span></span>
<span class="line"><span style="color:#E1E4E8;">        name,</span></span>
<span class="line"><span style="color:#E1E4E8;">        className,</span></span>
<span class="line"><span style="color:#E1E4E8;">        className,</span></span>
<span class="line"><span style="color:#E1E4E8;">        attrs.</span><span style="color:#B392F0;">toString</span><span style="color:#E1E4E8;">(),</span></span>
<span class="line"><span style="color:#E1E4E8;">        className,</span></span>
<span class="line"><span style="color:#E1E4E8;">        className,</span></span>
<span class="line"><span style="color:#E1E4E8;">        className</span></span>
<span class="line"><span style="color:#E1E4E8;">      ]);</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> _import </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">set</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">join</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;;</span><span style="color:#79B8FF;">\r\n</span><span style="color:#9ECBFF;">&quot;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">      _import </span><span style="color:#F97583;">+=</span><span style="color:#E1E4E8;"> _import.isEmpty </span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;&quot;</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">:</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;;&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">      dist </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> dist.</span><span style="color:#B392F0;">replaceFirst</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;%t&quot;</span><span style="color:#E1E4E8;">, _import);</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#6A737D;">//将生成的模板输出</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#79B8FF;">File</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;$</span><span style="color:#79B8FF;">DIST</span><span style="color:#9ECBFF;">$</span><span style="color:#79B8FF;">name</span><span style="color:#9ECBFF;">.dart&quot;</span><span style="color:#E1E4E8;">).</span><span style="color:#B392F0;">writeAsStringSync</span><span style="color:#E1E4E8;">(dist);</span></span>
<span class="line"><span style="color:#E1E4E8;">    }</span></span>
<span class="line"><span style="color:#E1E4E8;">  });</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">changeFirstChar</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> str, [</span><span style="color:#79B8FF;">bool</span><span style="color:#E1E4E8;"> upper </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">true</span><span style="color:#E1E4E8;">]) {</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> (upper </span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> str[</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">].</span><span style="color:#B392F0;">toUpperCase</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">:</span><span style="color:#E1E4E8;"> str[</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">].</span><span style="color:#B392F0;">toLowerCase</span><span style="color:#E1E4E8;">()) </span><span style="color:#F97583;">+</span></span>
<span class="line"><span style="color:#E1E4E8;">      str.</span><span style="color:#B392F0;">substring</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;">//将JSON类型转为对应的dart类型</span></span>
<span class="line"><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">getType</span><span style="color:#E1E4E8;">(v, </span><span style="color:#79B8FF;">Set</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">&gt; </span><span style="color:#F97583;">set</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> current) {</span></span>
<span class="line"><span style="color:#E1E4E8;">  current </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> current.</span><span style="color:#B392F0;">toLowerCase</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (v </span><span style="color:#F97583;">is</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">bool</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;bool&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">  } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (v </span><span style="color:#F97583;">is</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">num</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;num&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">  } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (v </span><span style="color:#F97583;">is</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;Map&lt;String,dynamic&gt;&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">  } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (v </span><span style="color:#F97583;">is</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">List</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;List&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">  } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (v </span><span style="color:#F97583;">is</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">) {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#6A737D;">//处理特殊标志</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (v.</span><span style="color:#B392F0;">startsWith</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;$</span><span style="color:#79B8FF;">TAG</span><span style="color:#9ECBFF;">[]&quot;</span><span style="color:#E1E4E8;">)) {</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> className </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">changeFirstChar</span><span style="color:#E1E4E8;">(v.</span><span style="color:#B392F0;">substring</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">3</span><span style="color:#E1E4E8;">), </span><span style="color:#79B8FF;">false</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (className.</span><span style="color:#B392F0;">toLowerCase</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">!=</span><span style="color:#E1E4E8;"> current) {</span></span>
<span class="line"><span style="color:#E1E4E8;">        </span><span style="color:#F97583;">set</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">add</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;import &quot;$</span><span style="color:#79B8FF;">className</span><span style="color:#9ECBFF;">.dart&quot;&#39;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">      }</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;List&lt;${</span><span style="color:#B392F0;">changeFirstChar</span><span style="color:#9ECBFF;">(</span><span style="color:#79B8FF;">className</span><span style="color:#9ECBFF;">)}&gt;&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">    } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (v.</span><span style="color:#B392F0;">startsWith</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">TAG</span><span style="color:#E1E4E8;">)) {</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">var</span><span style="color:#E1E4E8;"> fileName </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">changeFirstChar</span><span style="color:#E1E4E8;">(v.</span><span style="color:#B392F0;">substring</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">1</span><span style="color:#E1E4E8;">), </span><span style="color:#79B8FF;">false</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (fileName.</span><span style="color:#B392F0;">toLowerCase</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">!=</span><span style="color:#E1E4E8;"> current) {</span></span>
<span class="line"><span style="color:#E1E4E8;">        </span><span style="color:#F97583;">set</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">add</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&#39;import &quot;$</span><span style="color:#79B8FF;">fileName</span><span style="color:#9ECBFF;">.dart&quot;&#39;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">      }</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">changeFirstChar</span><span style="color:#E1E4E8;">(fileName);</span></span>
<span class="line"><span style="color:#E1E4E8;">    }</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;String&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">  } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;String&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">  }</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;">//替换模板占位符</span></span>
<span class="line"><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">format</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> fmt, </span><span style="color:#79B8FF;">List</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">Object</span><span style="color:#E1E4E8;">&gt; params) {</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">int</span><span style="color:#E1E4E8;"> matchIndex </span><span style="color:#F97583;">=</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">replace</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">Match</span><span style="color:#E1E4E8;"> m) {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">if</span><span style="color:#E1E4E8;"> (matchIndex </span><span style="color:#F97583;">&lt;</span><span style="color:#E1E4E8;"> params.length) {</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">switch</span><span style="color:#E1E4E8;"> (m[</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">]) {</span></span>
<span class="line"><span style="color:#E1E4E8;">        </span><span style="color:#F97583;">case</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;%s&quot;</span><span style="color:#F97583;">:</span></span>
<span class="line"><span style="color:#E1E4E8;">          </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> params[matchIndex</span><span style="color:#F97583;">++</span><span style="color:#E1E4E8;">].</span><span style="color:#B392F0;">toString</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"><span style="color:#E1E4E8;">      }</span></span>
<span class="line"><span style="color:#E1E4E8;">    } </span><span style="color:#F97583;">else</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#F97583;">throw</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">Exception</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;Missing parameter for string format&quot;</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">    }</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">throw</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">Exception</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;Invalid format string: &quot;</span><span style="color:#E1E4E8;"> </span><span style="color:#F97583;">+</span><span style="color:#E1E4E8;"> m[</span><span style="color:#79B8FF;">0</span><span style="color:#E1E4E8;">].</span><span style="color:#B392F0;">toString</span><span style="color:#E1E4E8;">());</span></span>
<span class="line"><span style="color:#E1E4E8;">  }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">return</span><span style="color:#E1E4E8;"> fmt.</span><span style="color:#B392F0;">replaceAllMapped</span><span style="color:#E1E4E8;">(</span><span style="color:#9ECBFF;">&quot;%s&quot;</span><span style="color:#E1E4E8;">, replace);</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">void</span><span style="color:#E1E4E8;"> </span><span style="color:#B392F0;">main</span><span style="color:#E1E4E8;">() {</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#B392F0;">walk</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;dart:convert&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;dart:io&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;package:path/path.dart&#39;</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">as</span><span style="color:#24292E;"> path;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">TAG</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;</span><span style="color:#005CC5;">\$</span><span style="color:#032F62;">&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">SRC</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;./json&quot;</span><span style="color:#24292E;">; </span><span style="color:#6A737D;">//JSON 目录</span></span>
<span class="line"><span style="color:#D73A49;">const</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">DIST</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;lib/models/&quot;</span><span style="color:#24292E;">; </span><span style="color:#6A737D;">//输出model目录</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">void</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">walk</span><span style="color:#24292E;">() {</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#6A737D;">//遍历JSON目录生成模板</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> src </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">Directory</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">SRC</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> list </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> src.</span><span style="color:#6F42C1;">listSync</span><span style="color:#24292E;">();</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> template </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">File</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;./template.dart&quot;</span><span style="color:#24292E;">).</span><span style="color:#6F42C1;">readAsStringSync</span><span style="color:#24292E;">();</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">File</span><span style="color:#24292E;"> file;</span></span>
<span class="line"><span style="color:#24292E;">  list.</span><span style="color:#6F42C1;">forEach</span><span style="color:#24292E;">((f) {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (</span><span style="color:#005CC5;">FileSystemEntity</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">isFileSync</span><span style="color:#24292E;">(f.path)) {</span></span>
<span class="line"><span style="color:#24292E;">      file </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">File</span><span style="color:#24292E;">(f.path);</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> paths </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> path.</span><span style="color:#6F42C1;">basename</span><span style="color:#24292E;">(f.path).</span><span style="color:#6F42C1;">split</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;.&quot;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> name </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> paths.first;</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (paths.last.</span><span style="color:#6F42C1;">toLowerCase</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">!=</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;json&quot;</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">||</span><span style="color:#24292E;"> name.</span><span style="color:#6F42C1;">startsWith</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;_&quot;</span><span style="color:#24292E;">)) </span><span style="color:#D73A49;">return</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (name.</span><span style="color:#6F42C1;">startsWith</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;_&quot;</span><span style="color:#24292E;">)) </span><span style="color:#D73A49;">return</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#6A737D;">//下面生成模板</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> map </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> json.</span><span style="color:#6F42C1;">decode</span><span style="color:#24292E;">(file.</span><span style="color:#6F42C1;">readAsStringSync</span><span style="color:#24292E;">());</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#6A737D;">//为了避免重复导入相同的包，我们用Set来保存生成的import语句。</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">set</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">Set</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">&gt;();</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#005CC5;">StringBuffer</span><span style="color:#24292E;"> attrs </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">StringBuffer</span><span style="color:#24292E;">();</span></span>
<span class="line"><span style="color:#24292E;">      (map </span><span style="color:#D73A49;">as</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt;).</span><span style="color:#6F42C1;">forEach</span><span style="color:#24292E;">((key, v) {</span></span>
<span class="line"><span style="color:#24292E;">        </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (key.</span><span style="color:#6F42C1;">startsWith</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;_&quot;</span><span style="color:#24292E;">)) </span><span style="color:#D73A49;">return</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">        </span><span style="color:#6A737D;">//所有字段都定义为可空</span></span>
<span class="line"><span style="color:#24292E;">        attrs.</span><span style="color:#6F42C1;">write</span><span style="color:#24292E;">(</span><span style="color:#6F42C1;">getType</span><span style="color:#24292E;">(v, </span><span style="color:#D73A49;">set</span><span style="color:#24292E;">, name)</span><span style="color:#D73A49;">+</span><span style="color:#032F62;">&quot;?&quot;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">        attrs.</span><span style="color:#6F42C1;">write</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot; &quot;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">        attrs.</span><span style="color:#6F42C1;">write</span><span style="color:#24292E;">(key);</span></span>
<span class="line"><span style="color:#24292E;">        attrs.</span><span style="color:#6F42C1;">writeln</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;;&quot;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">        attrs.</span><span style="color:#6F42C1;">write</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;    &quot;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">      });</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> className </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> name[</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">].</span><span style="color:#6F42C1;">toUpperCase</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">+</span><span style="color:#24292E;"> name.</span><span style="color:#6F42C1;">substring</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> dist </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">format</span><span style="color:#24292E;">(template, [</span></span>
<span class="line"><span style="color:#24292E;">        name,</span></span>
<span class="line"><span style="color:#24292E;">        className,</span></span>
<span class="line"><span style="color:#24292E;">        className,</span></span>
<span class="line"><span style="color:#24292E;">        attrs.</span><span style="color:#6F42C1;">toString</span><span style="color:#24292E;">(),</span></span>
<span class="line"><span style="color:#24292E;">        className,</span></span>
<span class="line"><span style="color:#24292E;">        className,</span></span>
<span class="line"><span style="color:#24292E;">        className</span></span>
<span class="line"><span style="color:#24292E;">      ]);</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> _import </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">set</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">join</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;;</span><span style="color:#005CC5;">\r\n</span><span style="color:#032F62;">&quot;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">      _import </span><span style="color:#D73A49;">+=</span><span style="color:#24292E;"> _import.isEmpty </span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;&quot;</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">:</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;;&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">      dist </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> dist.</span><span style="color:#6F42C1;">replaceFirst</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;%t&quot;</span><span style="color:#24292E;">, _import);</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#6A737D;">//将生成的模板输出</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#005CC5;">File</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;$</span><span style="color:#005CC5;">DIST</span><span style="color:#032F62;">$</span><span style="color:#005CC5;">name</span><span style="color:#032F62;">.dart&quot;</span><span style="color:#24292E;">).</span><span style="color:#6F42C1;">writeAsStringSync</span><span style="color:#24292E;">(dist);</span></span>
<span class="line"><span style="color:#24292E;">    }</span></span>
<span class="line"><span style="color:#24292E;">  });</span></span>
<span class="line"><span style="color:#24292E;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#005CC5;">String</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">changeFirstChar</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> str, [</span><span style="color:#005CC5;">bool</span><span style="color:#24292E;"> upper </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">true</span><span style="color:#24292E;">]) {</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> (upper </span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> str[</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">].</span><span style="color:#6F42C1;">toUpperCase</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">:</span><span style="color:#24292E;"> str[</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">].</span><span style="color:#6F42C1;">toLowerCase</span><span style="color:#24292E;">()) </span><span style="color:#D73A49;">+</span></span>
<span class="line"><span style="color:#24292E;">      str.</span><span style="color:#6F42C1;">substring</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;">//将JSON类型转为对应的dart类型</span></span>
<span class="line"><span style="color:#005CC5;">String</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">getType</span><span style="color:#24292E;">(v, </span><span style="color:#005CC5;">Set</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">&gt; </span><span style="color:#D73A49;">set</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> current) {</span></span>
<span class="line"><span style="color:#24292E;">  current </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> current.</span><span style="color:#6F42C1;">toLowerCase</span><span style="color:#24292E;">();</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (v </span><span style="color:#D73A49;">is</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">bool</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;bool&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">  } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (v </span><span style="color:#D73A49;">is</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">num</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;num&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">  } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (v </span><span style="color:#D73A49;">is</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;Map&lt;String,dynamic&gt;&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">  } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (v </span><span style="color:#D73A49;">is</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">List</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;List&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">  } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (v </span><span style="color:#D73A49;">is</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">String</span><span style="color:#24292E;">) {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#6A737D;">//处理特殊标志</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (v.</span><span style="color:#6F42C1;">startsWith</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;$</span><span style="color:#005CC5;">TAG</span><span style="color:#032F62;">[]&quot;</span><span style="color:#24292E;">)) {</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> className </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">changeFirstChar</span><span style="color:#24292E;">(v.</span><span style="color:#6F42C1;">substring</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">3</span><span style="color:#24292E;">), </span><span style="color:#005CC5;">false</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (className.</span><span style="color:#6F42C1;">toLowerCase</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">!=</span><span style="color:#24292E;"> current) {</span></span>
<span class="line"><span style="color:#24292E;">        </span><span style="color:#D73A49;">set</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">add</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;import &quot;$</span><span style="color:#005CC5;">className</span><span style="color:#032F62;">.dart&quot;&#39;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">      }</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;List&lt;${</span><span style="color:#6F42C1;">changeFirstChar</span><span style="color:#032F62;">(</span><span style="color:#005CC5;">className</span><span style="color:#032F62;">)}&gt;&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">    } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (v.</span><span style="color:#6F42C1;">startsWith</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">TAG</span><span style="color:#24292E;">)) {</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">var</span><span style="color:#24292E;"> fileName </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">changeFirstChar</span><span style="color:#24292E;">(v.</span><span style="color:#6F42C1;">substring</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">1</span><span style="color:#24292E;">), </span><span style="color:#005CC5;">false</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (fileName.</span><span style="color:#6F42C1;">toLowerCase</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">!=</span><span style="color:#24292E;"> current) {</span></span>
<span class="line"><span style="color:#24292E;">        </span><span style="color:#D73A49;">set</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">add</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&#39;import &quot;$</span><span style="color:#005CC5;">fileName</span><span style="color:#032F62;">.dart&quot;&#39;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">      }</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">changeFirstChar</span><span style="color:#24292E;">(fileName);</span></span>
<span class="line"><span style="color:#24292E;">    }</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;String&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">  } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;String&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">  }</span></span>
<span class="line"><span style="color:#24292E;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;">//替换模板占位符</span></span>
<span class="line"><span style="color:#005CC5;">String</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">format</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> fmt, </span><span style="color:#005CC5;">List</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">Object</span><span style="color:#24292E;">&gt; params) {</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">int</span><span style="color:#24292E;"> matchIndex </span><span style="color:#D73A49;">=</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">0</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">replace</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">Match</span><span style="color:#24292E;"> m) {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">if</span><span style="color:#24292E;"> (matchIndex </span><span style="color:#D73A49;">&lt;</span><span style="color:#24292E;"> params.length) {</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">switch</span><span style="color:#24292E;"> (m[</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">]) {</span></span>
<span class="line"><span style="color:#24292E;">        </span><span style="color:#D73A49;">case</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;%s&quot;</span><span style="color:#D73A49;">:</span></span>
<span class="line"><span style="color:#24292E;">          </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> params[matchIndex</span><span style="color:#D73A49;">++</span><span style="color:#24292E;">].</span><span style="color:#6F42C1;">toString</span><span style="color:#24292E;">();</span></span>
<span class="line"><span style="color:#24292E;">      }</span></span>
<span class="line"><span style="color:#24292E;">    } </span><span style="color:#D73A49;">else</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#D73A49;">throw</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">Exception</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;Missing parameter for string format&quot;</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">    }</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">throw</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">Exception</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;Invalid format string: &quot;</span><span style="color:#24292E;"> </span><span style="color:#D73A49;">+</span><span style="color:#24292E;"> m[</span><span style="color:#005CC5;">0</span><span style="color:#24292E;">].</span><span style="color:#6F42C1;">toString</span><span style="color:#24292E;">());</span></span>
<span class="line"><span style="color:#24292E;">  }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">return</span><span style="color:#24292E;"> fmt.</span><span style="color:#6F42C1;">replaceAllMapped</span><span style="color:#24292E;">(</span><span style="color:#032F62;">&quot;%s&quot;</span><span style="color:#24292E;">, replace);</span></span>
<span class="line"><span style="color:#24292E;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">void</span><span style="color:#24292E;"> </span><span style="color:#6F42C1;">main</span><span style="color:#24292E;">() {</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#6F42C1;">walk</span><span style="color:#24292E;">();</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div></li><li><p>写一个shell(mo.sh)，将生成模板和生成model串起来：</p><div class="language-sh vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">sh</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">dart</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">mo.dart</span></span>
<span class="line"><span style="color:#B392F0;">flutter</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">packages</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">pub</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">run</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">build_runner</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">build</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">--delete-conflicting-outputs</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">dart</span><span style="color:#24292E;"> </span><span style="color:#032F62;">mo.dart</span></span>
<span class="line"><span style="color:#6F42C1;">flutter</span><span style="color:#24292E;"> </span><span style="color:#032F62;">packages</span><span style="color:#24292E;"> </span><span style="color:#032F62;">pub</span><span style="color:#24292E;"> </span><span style="color:#032F62;">run</span><span style="color:#24292E;"> </span><span style="color:#032F62;">build_runner</span><span style="color:#24292E;"> </span><span style="color:#032F62;">build</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">--delete-conflicting-outputs</span></span></code></pre></div></li></ol><p>至此，我们的脚本写好了，我们在根目录下新建一个json目录，然后把user.json移进去，然后在lib目录下创建一个models目录，用于保存最终生成的Model类。现在我们只需要一句命令即可生成Model类了:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">./mo.sh</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">./mo.sh</span></span></code></pre></div><p>运行后，一切都将自动执行，现在好多了。但是上面脚本只是处理简单 JSON 的情况，还不能很好处理 JSON 嵌套和数组。</p><h3 id="_2-嵌套json处理" tabindex="-1">2. 嵌套JSON处理 <a class="header-anchor" href="#_2-嵌套json处理" aria-label="Permalink to &quot;2. 嵌套JSON处理&quot;">​</a></h3><p>我们创建一个person.json文件，内容如下：</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#E1E4E8;">{</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;John Smith&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;email&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;john@example.com&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;mother&quot;</span><span style="color:#E1E4E8;">:{</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;Alice&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">&quot;email&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;alice@example.com&quot;</span></span>
<span class="line"><span style="color:#E1E4E8;">  },</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;friends&quot;</span><span style="color:#E1E4E8;">:[</span></span>
<span class="line"><span style="color:#E1E4E8;">    {</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;Jack&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#79B8FF;">&quot;email&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;Jack@example.com&quot;</span></span>
<span class="line"><span style="color:#E1E4E8;">    },</span></span>
<span class="line"><span style="color:#E1E4E8;">    {</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;Nancy&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#79B8FF;">&quot;email&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;Nancy@example.com&quot;</span></span>
<span class="line"><span style="color:#E1E4E8;">    }</span></span>
<span class="line"><span style="color:#E1E4E8;">  ]</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;">{</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;John Smith&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;email&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;john@example.com&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;mother&quot;</span><span style="color:#24292E;">:{</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;Alice&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">&quot;email&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;alice@example.com&quot;</span></span>
<span class="line"><span style="color:#24292E;">  },</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;friends&quot;</span><span style="color:#24292E;">:[</span></span>
<span class="line"><span style="color:#24292E;">    {</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;Jack&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#005CC5;">&quot;email&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;Jack@example.com&quot;</span></span>
<span class="line"><span style="color:#24292E;">    },</span></span>
<span class="line"><span style="color:#24292E;">    {</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;Nancy&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#005CC5;">&quot;email&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;Nancy@example.com&quot;</span></span>
<span class="line"><span style="color:#24292E;">    }</span></span>
<span class="line"><span style="color:#24292E;">  ]</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>每个Person都有<code>name</code> 、<code>email</code> 、 <code>mother</code>和<code>friends</code>四个字段，由于<code>mother</code>也是一个Person，朋友是多个Person(数组)，所以我们期望生成的Model是下面这样：</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#F97583;">part</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;person.g.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">@JsonSerializable</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">Person</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">Person</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">String</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> name;</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">String</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> email;</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">Person</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> mother;</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">List</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">Person</span><span style="color:#E1E4E8;">&gt;</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> friends;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">factory</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">Person</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">fromJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; json) </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">_$PersonFromJson</span><span style="color:#E1E4E8;">(json);</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; </span><span style="color:#B392F0;">toJson</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">_$PersonToJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#D73A49;">part</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;person.g.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">@JsonSerializable</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">Person</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">Person</span><span style="color:#24292E;">();</span></span>
<span class="line"><span style="color:#24292E;">    </span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">String</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> name;</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">String</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> email;</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">Person</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> mother;</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">List</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">Person</span><span style="color:#24292E;">&gt;</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> friends;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">factory</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">Person</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">fromJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; json) </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">_$PersonFromJson</span><span style="color:#24292E;">(json);</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; </span><span style="color:#6F42C1;">toJson</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">_$PersonToJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>这时，我们只需要简单修改一下JSON，添加一些特殊标志，重新运行mo.sh即可：</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#E1E4E8;">{</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;John Smith&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;email&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;john@example.com&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;mother&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;$person&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;friends&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;$[]person&quot;</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;">{</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;John Smith&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;email&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;john@example.com&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;mother&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;$person&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;friends&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;$[]person&quot;</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>我们使用美元符“$”作为特殊标志符(如果与内容冲突，可以修改mo.dart中的<code>TAG</code>常量，自定义标志符)，脚本在遇到特殊标志符后会先把相应字段转为相应的对象或对象数组，对象数组需要在标志符后面添加数组符“[]”，符号后面接具体的类型名，此例中是person。其他类型同理，加入我们给User添加一个Person类型的 <code>boss</code>字段：</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#E1E4E8;">{</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;John Smith&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;email&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;john@example.com&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;boss&quot;</span><span style="color:#E1E4E8;">:</span><span style="color:#9ECBFF;">&quot;$person&quot;</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;">{</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;John Smith&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;email&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;john@example.com&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;boss&quot;</span><span style="color:#24292E;">:</span><span style="color:#032F62;">&quot;$person&quot;</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>重新运行mo.sh，生成的user.dart如下：</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&quot;person.dart&quot;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#F97583;">part</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;user.g.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">@JsonSerializable</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">String</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> name;</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">String</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> email;</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">Person</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> boss;</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#F97583;">factory</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">fromJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; json) </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">_$UserFromJson</span><span style="color:#E1E4E8;">(json);</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; </span><span style="color:#B392F0;">toJson</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">_$UserToJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&quot;person.dart&quot;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#D73A49;">part</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;user.g.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">@JsonSerializable</span><span style="color:#24292E;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">User</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">String</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> name;</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">String</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> email;</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">Person</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> boss;</span></span>
<span class="line"><span style="color:#24292E;">    </span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#D73A49;">factory</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">fromJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; json) </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">_$UserFromJson</span><span style="color:#24292E;">(json);</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; </span><span style="color:#6F42C1;">toJson</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">_$UserToJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>可以看到，<code>boss</code>字段已自动添加，并自动导入了“person.dart”。</p><h3 id="_3-json-model-包" tabindex="-1">3. Json_model 包 <a class="header-anchor" href="#_3-json-model-包" aria-label="Permalink to &quot;3. Json_model 包&quot;">​</a></h3><p>我们上面实现的脚本只是一个乞丐版，还有很多功能不支持，比如默认生成的变量都是可空类型、不支持导入其他的dart文件、不支持生成注释等等，为此，笔者专门发布了一个功能完成的 <a href="https://github.com/flutterchina/json_model" target="_blank" rel="noreferrer">Json_model</a>包，具备灵活的配置和自定义功能，开发者把该包加入开发依赖后，便可以用一条命令，根据Json文件生成Dart类，下面是一个简单的功能演示：</p><p>JSON 文件如下：</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#E1E4E8;">{</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;@meta&quot;</span><span style="color:#E1E4E8;">: { </span><span style="color:#6A737D;">// @meta 可以定制单个 json 的生成规则，默认使用全局配置</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">&quot;import&quot;</span><span style="color:#E1E4E8;">: [</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#9ECBFF;">&quot;test_dir/profile.dart&quot;</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// 导入其他文件</span></span>
<span class="line"><span style="color:#E1E4E8;">    ],</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">&quot;comments&quot;</span><span style="color:#E1E4E8;">: {</span></span>
<span class="line"><span style="color:#E1E4E8;">      </span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;名字&quot;</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// 给 &quot;name&quot; 字段添加注释</span></span>
<span class="line"><span style="color:#E1E4E8;">    },</span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">&quot;nullable&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#79B8FF;">false</span><span style="color:#E1E4E8;">, </span><span style="color:#6A737D;">// 字段默认非可空，会生成 late </span></span>
<span class="line"><span style="color:#E1E4E8;">    </span><span style="color:#79B8FF;">&quot;ignore&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#79B8FF;">false</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// 是否跳过当前 JSON 的 model 类生成</span></span>
<span class="line"><span style="color:#E1E4E8;">  },</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;@JsonKey(ignore: true) Profile?&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;profile&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;@JsonKey(name: &#39;+1&#39;) int?&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;loved&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;name&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;wendux&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;father&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;$user&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;friends&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;$[]user&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;keywords&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#9ECBFF;">&quot;$[]String&quot;</span><span style="color:#E1E4E8;">,</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">&quot;age?&quot;</span><span style="color:#E1E4E8;">: </span><span style="color:#79B8FF;">20</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;">// 指定 age 字段可空</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292E;">{</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;@meta&quot;</span><span style="color:#24292E;">: { </span><span style="color:#6A737D;">// @meta 可以定制单个 json 的生成规则，默认使用全局配置</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">&quot;import&quot;</span><span style="color:#24292E;">: [</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#032F62;">&quot;test_dir/profile.dart&quot;</span><span style="color:#24292E;"> </span><span style="color:#6A737D;">// 导入其他文件</span></span>
<span class="line"><span style="color:#24292E;">    ],</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">&quot;comments&quot;</span><span style="color:#24292E;">: {</span></span>
<span class="line"><span style="color:#24292E;">      </span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;名字&quot;</span><span style="color:#24292E;"> </span><span style="color:#6A737D;">// 给 &quot;name&quot; 字段添加注释</span></span>
<span class="line"><span style="color:#24292E;">    },</span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">&quot;nullable&quot;</span><span style="color:#24292E;">: </span><span style="color:#005CC5;">false</span><span style="color:#24292E;">, </span><span style="color:#6A737D;">// 字段默认非可空，会生成 late </span></span>
<span class="line"><span style="color:#24292E;">    </span><span style="color:#005CC5;">&quot;ignore&quot;</span><span style="color:#24292E;">: </span><span style="color:#005CC5;">false</span><span style="color:#24292E;"> </span><span style="color:#6A737D;">// 是否跳过当前 JSON 的 model 类生成</span></span>
<span class="line"><span style="color:#24292E;">  },</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;@JsonKey(ignore: true) Profile?&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;profile&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;@JsonKey(name: &#39;+1&#39;) int?&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;loved&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;name&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;wendux&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;father&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;$user&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;friends&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;$[]user&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;keywords&quot;</span><span style="color:#24292E;">: </span><span style="color:#032F62;">&quot;$[]String&quot;</span><span style="color:#24292E;">,</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">&quot;age?&quot;</span><span style="color:#24292E;">: </span><span style="color:#005CC5;">20</span><span style="color:#24292E;"> </span><span style="color:#6A737D;">// 指定 age 字段可空</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><p>生成的 Model 类如下：</p><div class="language-dart vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dart</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#F97583;">import</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;test_dir/profile.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"><span style="color:#F97583;">part</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;user.g.dart&#39;</span><span style="color:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583;">@JsonSerializable</span><span style="color:#E1E4E8;">()</span></span>
<span class="line"><span style="color:#F97583;">class</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;"> {</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">@JsonKey</span><span style="color:#E1E4E8;">(ignore</span><span style="color:#F97583;">:</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">true</span><span style="color:#E1E4E8;">) </span><span style="color:#79B8FF;">Profile</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> profile;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">@JsonKey</span><span style="color:#E1E4E8;">(name</span><span style="color:#F97583;">:</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">&#39;+1&#39;</span><span style="color:#E1E4E8;">) </span><span style="color:#79B8FF;">int</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> loved;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#6A737D;">//名字</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">late</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;"> name;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">late</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;"> father;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">late</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">List</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">&gt; friends;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">late</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">List</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">&gt; keywords;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">num</span><span style="color:#F97583;">?</span><span style="color:#E1E4E8;"> age;</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#F97583;">factory</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">User</span><span style="color:#E1E4E8;">.</span><span style="color:#B392F0;">fromJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">,</span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; json) </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">_$UserFromJson</span><span style="color:#E1E4E8;">(json);</span></span>
<span class="line"><span style="color:#E1E4E8;">  </span><span style="color:#79B8FF;">Map</span><span style="color:#E1E4E8;">&lt;</span><span style="color:#79B8FF;">String</span><span style="color:#E1E4E8;">, </span><span style="color:#79B8FF;">dynamic</span><span style="color:#E1E4E8;">&gt; </span><span style="color:#B392F0;">toJson</span><span style="color:#E1E4E8;">() </span><span style="color:#F97583;">=&gt;</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">_$UserToJson</span><span style="color:#E1E4E8;">(</span><span style="color:#79B8FF;">this</span><span style="color:#E1E4E8;">);</span></span>
<span class="line"><span style="color:#E1E4E8;">}</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;package:json_annotation/json_annotation.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#D73A49;">import</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;test_dir/profile.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"><span style="color:#D73A49;">part</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;user.g.dart&#39;</span><span style="color:#24292E;">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D73A49;">@JsonSerializable</span><span style="color:#24292E;">()</span></span>
<span class="line"><span style="color:#D73A49;">class</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">User</span><span style="color:#24292E;"> {</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">@JsonKey</span><span style="color:#24292E;">(ignore</span><span style="color:#D73A49;">:</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">true</span><span style="color:#24292E;">) </span><span style="color:#005CC5;">Profile</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> profile;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">@JsonKey</span><span style="color:#24292E;">(name</span><span style="color:#D73A49;">:</span><span style="color:#24292E;"> </span><span style="color:#032F62;">&#39;+1&#39;</span><span style="color:#24292E;">) </span><span style="color:#005CC5;">int</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> loved;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#6A737D;">//名字</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">late</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">String</span><span style="color:#24292E;"> name;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">late</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">User</span><span style="color:#24292E;"> father;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">late</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">List</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">User</span><span style="color:#24292E;">&gt; friends;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">late</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">List</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">&gt; keywords;</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">num</span><span style="color:#D73A49;">?</span><span style="color:#24292E;"> age;</span></span>
<span class="line"><span style="color:#24292E;">  </span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#D73A49;">factory</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">User</span><span style="color:#24292E;">.</span><span style="color:#6F42C1;">fromJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">,</span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; json) </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">_$UserFromJson</span><span style="color:#24292E;">(json);</span></span>
<span class="line"><span style="color:#24292E;">  </span><span style="color:#005CC5;">Map</span><span style="color:#24292E;">&lt;</span><span style="color:#005CC5;">String</span><span style="color:#24292E;">, </span><span style="color:#005CC5;">dynamic</span><span style="color:#24292E;">&gt; </span><span style="color:#6F42C1;">toJson</span><span style="color:#24292E;">() </span><span style="color:#D73A49;">=&gt;</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">_$UserToJson</span><span style="color:#24292E;">(</span><span style="color:#005CC5;">this</span><span style="color:#24292E;">);</span></span>
<span class="line"><span style="color:#24292E;">}</span></span></code></pre></div><h2 id="_11-7-3-使用ide插件生成model" tabindex="-1">11.7.3 使用IDE插件生成model <a class="header-anchor" href="#_11-7-3-使用ide插件生成model" aria-label="Permalink to &quot;11.7.3 使用IDE插件生成model&quot;">​</a></h2><p>目前Android Studio(或IntelliJ)有几个插件，可以将json文件转成Model类，但插件质量参差不齐，甚至还有一些沾染上了抄袭风波，故笔者在此不做优先推荐，读者有兴趣可以自行了解。但是，我们还是要了解一下IDE插件和<a href="https://github.com/flutterchina/json_model" target="_blank" rel="noreferrer">Json_model</a>的优劣：</p><ol><li><a href="https://github.com/flutterchina/json_model" target="_blank" rel="noreferrer">Json_model</a>需要单独维护一个存放Json文件的文件夹，如果有改动，只需修改Json文件便可重新生成Model类；而IDE插件一般需要用户手动将Json内容拷贝复制到一个输入框中，这样生成之后Json文件没有存档的化，之后要改动就需要手动。</li><li><a href="https://github.com/flutterchina/json_model" target="_blank" rel="noreferrer">Json_model</a>可以手动指定某个字段引用的其他Model类，可以避免生成重复的类；而IDE插件一般会为每一个Json文件中所有嵌套对象都单独生成一个Model类，即使这些嵌套对象可能在其他Model类中已经生成过。</li><li><a href="https://github.com/flutterchina/json_model" target="_blank" rel="noreferrer">Json_model</a> 提供了命令行转化方式，可以方便集成到CI等非UI环境的场景。</li></ol><h2 id="_11-7-4-faq" tabindex="-1">11.7.4 FAQ <a class="header-anchor" href="#_11-7-4-faq" aria-label="Permalink to &quot;11.7.4 FAQ&quot;">​</a></h2><p>很多人可能会问 Flutter 中有没有像 Java 开发中的 Gson/Jackson 一样的Json序列化类库？答案是没有！因为这样的库需要使用运行时反射，这在 Flutter 中是禁用的。运行时反射会干扰 Dart 的 <em>tree shaking</em>，使用_tree shaking_，可以在 release 版中“去除”未使用的代码，这可以显著优化应用程序的大小。由于反射会默认应用到所有代码，因此_tree shaking_ 会很难工作，因为在启用反射时很难知道哪些代码未被使用，因此冗余代码很难剥离，所以 Flutter 中禁用了 Dart 的反射功能，而正因如此也就无法实现动态转化 Model 的功能。</p></div></div></main><footer class="VPDocFooter" data-v-6b87e69f data-v-ef5dee53><!--[--><!--]--><div class="edit-info" data-v-ef5dee53><div class="edit-link" data-v-ef5dee53><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://gitee.com/luoguangguang/note/tree/master/docs/largeFrontEnd/flutter/chapter11/json_model.md" target="_blank" rel="noreferrer" data-v-ef5dee53><!--[--><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="edit-link-icon" aria-label="edit icon" data-v-ef5dee53><path d="M18,23H4c-1.7,0-3-1.3-3-3V6c0-1.7,1.3-3,3-3h7c0.6,0,1,0.4,1,1s-0.4,1-1,1H4C3.4,5,3,5.4,3,6v14c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1v-7c0-0.6,0.4-1,1-1s1,0.4,1,1v7C21,21.7,19.7,23,18,23z"></path><path d="M8,17c-0.3,0-0.5-0.1-0.7-0.3C7,16.5,6.9,16.1,7,15.8l1-4c0-0.2,0.1-0.3,0.3-0.5l9.5-9.5c1.2-1.2,3.2-1.2,4.4,0c1.2,1.2,1.2,3.2,0,4.4l-9.5,9.5c-0.1,0.1-0.3,0.2-0.5,0.3l-4,1C8.2,17,8.1,17,8,17zM9.9,12.5l-0.5,2.1l2.1-0.5l9.3-9.3c0.4-0.4,0.4-1.1,0-1.6c-0.4-0.4-1.2-0.4-1.6,0l0,0L9.9,12.5z M18.5,2.5L18.5,2.5L18.5,2.5z"></path></svg> 在Gitee上参与编辑此页<!--]--></a></div><!----></div><nav class="prev-next" data-v-ef5dee53><div class="pager" data-v-ef5dee53><!----></div><div class="pager" data-v-ef5dee53><a class="pager-link next" href="./largeFrontEnd/flutter/chapter1/index.html" data-v-ef5dee53><span class="desc" data-v-ef5dee53>Next page</span><span class="title" data-v-ef5dee53>第一章 初识Flutter</span></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-1919c326 data-v-e03eb2e1><div class="container" data-v-e03eb2e1><p class="message" data-v-e03eb2e1>Released under the MIT License.</p><p class="copyright" data-v-e03eb2e1>Copyright © 2023-present LG of GZU</p></div></footer><!--[--><!--]--></div></div>
    <script>window.__VP_HASH_MAP__=JSON.parse("{\"backend_index.md\":\"0cb07c7c\",\"largefrontend_electron_index.md\":\"adab8e13\",\"largefrontend_flutter_chapter1_index.md\":\"5106cc23\",\"index.md\":\"20a66851\",\"largefrontend_flutter_chapter10_intro.md\":\"5756d1e8\",\"largefrontend_flutter_chapter10_index.md\":\"87e47f16\",\"largefrontend_flutter_chapter1_flutter_intro.md\":\"9ad5fc78\",\"largefrontend_flutter_chapter12_package_and_plugin.md\":\"c2f14cd7\",\"largefrontend_flutter_chapter12_flutter_web.md\":\"f4b6b743\",\"largefrontend_flutter_chapter10_combine.md\":\"333319d8\",\"largefrontend_flutter_chapter14_flutter_ui_system.md\":\"a1011f7b\",\"largefrontend_flutter_chapter11_index.md\":\"35dcdd7c\",\"largefrontend_flutter_chapter12_index.md\":\"890b799c\",\"largefrontend_flutter_chapter13_index.md\":\"6db9b579\",\"largefrontend_flutter_chapter14_index.md\":\"87f7da6b\",\"largefrontend_flutter_chapter1_mobile_development_intro.md\":\"40c15ac2\",\"largefrontend_flutter_chapter10_turn_box.md\":\"6a792fe1\",\"largefrontend_flutter_chapter3_index.md\":\"bc1d0de5\",\"largefrontend_flutter_chapter4_stack.md\":\"3f5c3186\",\"largefrontend_flutter_chapter1_install_flutter.md\":\"4543c368\",\"largefrontend_flutter_chapter14_paint.md\":\"8f7289b0\",\"largefrontend_flutter_chapter5_padding.md\":\"9fadce05\",\"largefrontend_flutter_chapter4_index.md\":\"f9b298f7\",\"largefrontend_flutter_chapter2_flutter_package_mgr.md\":\"4a3b7161\",\"largefrontend_flutter_chapter11_socket.md\":\"e8264e44\",\"largefrontend_flutter_chapter4_intro.md\":\"1341b5fd\",\"largefrontend_flutter_chapter14_update.md\":\"e4d2c2f0\",\"largefrontend_flutter_chapter5_index.md\":\"455baa0a\",\"largefrontend_flutter_chapter4_alignment.md\":\"a6596610\",\"largefrontend_flutter_chapter13_multi_languages_support.md\":\"c113238d\",\"largefrontend_flutter_chapter11_dio.md\":\"64f4e813\",\"largefrontend_flutter_chapter2_first_flutter_app.md\":\"b650181d\",\"largefrontend_flutter_chapter2_flutter_app_debug.md\":\"67a72433\",\"largefrontend_flutter_chapter2_state_manage.md\":\"9bb80d37\",\"largefrontend_flutter_chapter6_index.md\":\"5a321b81\",\"largefrontend_flutter_chapter5_material_scaffold.md\":\"8e6b896a\",\"largefrontend_flutter_chapter3_buttons.md\":\"ef950360\",\"largefrontend_flutter_chapter10_done_widget.md\":\"c3b44318\",\"largefrontend_flutter_chapter6_single_child_scrollview.md\":\"e3f75f3b\",\"largefrontend_flutter_chapter14_paint_flow.md\":\"d2f8102a\",\"largefrontend_flutter_chapter6_intro.md\":\"125a064e\",\"largefrontend_flutter_chapter5_transform.md\":\"22708e1e\",\"largefrontend_flutter_chapter14_layer.md\":\"4ed449fc\",\"largefrontend_flutter_chapter11_websocket.md\":\"0a022e47\",\"largefrontend_flutter_chapter5_fittedbox.md\":\"db915726\",\"largefrontend_flutter_chapter2_index.md\":\"d8e937b7\",\"largefrontend_flutter_chapter3_radio_and_checkbox.md\":\"025aba21\",\"largefrontend_flutter_chapter13_locallization_implement.md\":\"dc4b83fe\",\"largefrontend_flutter_chapter2_thread_model_and_error_report.md\":\"a29199d6\",\"largefrontend_flutter_chapter5_decoratedbox.md\":\"20f093ba\",\"largefrontend_flutter_chapter14_render_object.md\":\"55a1b551\",\"largefrontend_flutter_chapter14_element_buildcontext.md\":\"4272eae4\",\"largefrontend_flutter_chapter4_wrap_and_flow.md\":\"ac41b5bd\",\"largefrontend_flutter_chapter11_file_operation.md\":\"996a3a5d\",\"largefrontend_flutter_chapter13_faq.md\":\"ba7b9c70\",\"largefrontend_webfrontend_md_10.md\":\"51e0a312\",\"largefrontend_webfrontend_md_24.md\":\"0a4abd08\",\"largefrontend_flutter_chapter14_flutter_app_startup.md\":\"9b5942a1\",\"largefrontend_flutter_chapter10_custom_paint.md\":\"8b2a0a46\",\"largefrontend_flutter_chapter2_flutter_assets_mgr.md\":\"0e38b701\",\"largefrontend_interview_01.md\":\"2ac4b56d\",\"largefrontend_flutter_chapter8_index.md\":\"e83d3d80\",\"largefrontend_webfrontend_md_16.md\":\"a5610416\",\"largefrontend_flutter_chapter9_index.md\":\"3fb342a7\",\"largefrontend_flutter_chapter8_listener.md\":\"1b9b0316\",\"largefrontend_webfrontend_md_37.md\":\"3cacf3a2\",\"largefrontend_flutter_chapter4_layoutbuilder.md\":\"3d4bf94b\",\"largefrontend_webfrontend_md_17.md\":\"ee74edfb\",\"largefrontend_webfrontend_md_13.md\":\"b180bb5b\",\"largefrontend_flutter_chapter7_index.md\":\"0eb456b2\",\"largefrontend_webfrontend_md_31.md\":\"309453c7\",\"largefrontend_webfrontend_md_25.md\":\"95fdb4fe\",\"largefrontend_webfrontend_md_12.md\":\"3b14e491\",\"largefrontend_webfrontend_md_23.md\":\"18f08d72\",\"largefrontend_flutter_chapter11_json_model.md\":\"c84d2ccf\",\"largefrontend_webfrontend_md_01.md\":\"fbb7a35f\",\"largefrontend_flutter_chapter3_progress.md\":\"9bc148d3\",\"largefrontend_webfrontend_md_18.md\":\"ee651cc6\",\"largefrontend_flutter_sponsor.md\":\"e71431a9\",\"largefrontend_webfrontend_md_36.md\":\"f22f6d0d\",\"largefrontend_webfrontend_md_07.md\":\"71c2ad1d\",\"largefrontend_webfrontend_md_19.md\":\"e7907728\",\"largefrontend_webfrontend_md_20.md\":\"5a68bb4f\",\"largefrontend_webfrontend_md_32.md\":\"91d2f39f\",\"largefrontend_flutter_chapter7_futurebuilder_and_streambuilder.md\":\"af3535c0\",\"largefrontend_flutter_chapter9_hero.md\":\"25b46cf2\",\"largefrontend_flutter_chapter8_notification.md\":\"909f6756\",\"largefrontend_webfrontend_md_08.md\":\"0d59dce4\",\"largefrontend_flutter_chapter3_img_and_icon.md\":\"8b409b55\",\"largefrontend_webfrontend_md_04.md\":\"d6c15d55\",\"largefrontend_flutter_chapter9_animated_switcher.md\":\"9c0b3119\",\"largefrontend_webfrontend_md_22.md\":\"7d6fea68\",\"largefrontend_flutter_chapter2_flutter_widget_intro.md\":\"13414fea\",\"largefrontend_flutter_chapter13_intl.md\":\"d4776610\",\"largefrontend_overview_index.md\":\"3c87f69c\",\"largefrontend_flutter_chapter5_container.md\":\"373cc694\",\"largefrontend_wechatminiprogram_index.md\":\"7f40708d\",\"largefrontend_webfrontend_md_38.md\":\"3b6bb332\",\"linux_index.md\":\"624ecc66\",\"largefrontend_webfrontend_md_35.md\":\"f0538423\",\"myteam_index.md\":\"91a2c11f\",\"largefrontend_flutter_chapter6_pageview.md\":\"36fcbc65\",\"largefrontend_webfrontend_md_03.md\":\"2e5087f0\",\"largefrontend_webfrontend_md_21.md\":\"c181316e\",\"largefrontend_flutter_chapter3_input_and_form.md\":\"e4fba9dd\",\"largefrontend_flutter_chapter14_compositing.md\":\"6d96f932\",\"largefrontend_webfrontend_md_29.md\":\"c6fada7d\",\"largefrontend_flutter_chapter4_constraints.md\":\"9e4baace\",\"largefrontend_webfrontend_md_11.md\":\"63cd9c49\",\"largefrontend_webfrontend_md_14.md\":\"1423aeb1\",\"largefrontend_flutter_chapter6_tabview.md\":\"56048fb1\",\"largefrontend_webfrontend_md_33.md\":\"fdbe86fa\",\"largefrontend_flutter_chapter6_nestedscrollview.md\":\"2a66b86a\",\"largefrontend_webfrontend_md_34.md\":\"ad8ea220\",\"largefrontend_flutter_chapter2_flutter_router.md\":\"bb6e776c\",\"largefrontend_webfrontend_md_30.md\":\"cd2cb5aa\",\"largefrontend_flutter_chapter4_flex.md\":\"ebd43d6a\",\"largefrontend_webfrontend_md_09.md\":\"eedafcb1\",\"largefrontend_webfrontend_md_40.md\":\"4d4fefa1\",\"largefrontend_flutter_join_us.md\":\"44c81d86\",\"largefrontend_flutter_chapter9_route_transition.md\":\"f56cf837\",\"largefrontend_uniapp_index.md\":\"fa387c39\",\"largefrontend_flutter_chapter4_row_and_column.md\":\"964229f5\",\"largefrontend_flutter_chapter9_stagger_animation.md\":\"315538f5\",\"largefrontend_flutter_chapter3_text.md\":\"6720230c\",\"largefrontend_flutter_chapter10_watermark.md\":\"2e4ddf03\",\"largefrontend_flutter_chapter11_http.md\":\"efd2ee64\",\"largefrontend_webfrontend_md_06.md\":\"e20b049a\",\"largefrontend_flutter_summary.md\":\"2e31b0a8\",\"largefrontend_flutter_chapter6_animatedlist.md\":\"20d9436f\",\"largefrontend_flutter_chapter5_clip.md\":\"91f4174c\",\"largefrontend_webfrontend_md_02.md\":\"40cd2099\",\"largefrontend_flutter_chapter6_gridview.md\":\"b3be7e60\",\"largefrontend_flutter_chapter6_custom_scrollview.md\":\"01be950c\",\"largefrontend_flutter_chapter11_download_with_chunks.md\":\"9379cc89\",\"largefrontend_flutter_chapter6_scroll_controller.md\":\"ffa2d5fd\",\"largefrontend_flutter_chapter9_intro.md\":\"3fc29b5f\",\"largefrontend_flutter_chapter1_dart.md\":\"6bba4e7c\",\"largefrontend_flutter_chapter7_inherited_widget.md\":\"5a21d704\",\"largefrontend_flutter_index.md\":\"cd81fbbe\",\"largefrontend_flutter_reference.md\":\"36336375\",\"largefrontend_flutter_chapter6_keepalive.md\":\"535137be\",\"largefrontend_flutter_chapter14_layout.md\":\"0d7a8df3\",\"largefrontend_flutter_chapter6_sliver.md\":\"0c8b7553\",\"largefrontend_webfrontend_md_39.md\":\"aef49a57\",\"largefrontend_webfrontend_md_15.md\":\"bf9ff1a1\",\"largefrontend_flutter_chapter14_image_and_cache.md\":\"9622c56b\",\"largefrontend_webfrontend_md_28.md\":\"83169d10\",\"largefrontend_flutter_chapter8_eventbus.md\":\"fc0db86d\",\"largefrontend_flutter_chapter7_value_listenable_builder.md\":\"a0c76121\",\"largefrontend_flutter_preface.md\":\"604b9934\",\"largefrontend_flutter_chapter7_theme.md\":\"c21036bc\",\"largefrontend_webfrontend_md_05.md\":\"f7607009\",\"largefrontend_flutter_chapter6_listview.md\":\"472910bd\",\"largefrontend_flutter_chapter7_provider.md\":\"ab590744\",\"largefrontend_flutter_chapter8_gesture.md\":\"859bbb38\",\"largefrontend_flutter_chapter9_animated_widgets.md\":\"e8cd3c4d\",\"largefrontend_webfrontend_md_26.md\":\"4928006b\",\"largefrontend_flutter_chapter10_gradient_circular_progress_demo.md\":\"b3d48a2c\",\"largefrontend_flutter_chapter8_hittest.md\":\"e963812b\",\"largefrontend_flutter_chapter7_willpopscope.md\":\"d224ecce\",\"largefrontend_flutter_chapter9_animation_structure.md\":\"672eb3c0\",\"largefrontend_flutter_chapter8_gesture_conflict.md\":\"15bbadba\",\"largefrontend_webfrontend_md_27.md\":\"0b5b5e39\",\"largefrontend_flutter_chapter7_dailog.md\":\"5f91e51a\",\"largefrontend_flutter_chapter10_custom_checkbox.md\":\"0db7d50f\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"落光的Pro博客\",\"description\":\"Vite & Vue powered static site generator.\",\"base\":\"./\",\"head\":[],\"appearance\":true,\"themeConfig\":{\"search\":{\"provider\":\"local\",\"options\":{\"locales\":{\"zh\":{\"translations\":{\"button\":{\"buttonText\":\"搜索文档\",\"buttonAriaLabel\":\"搜索文档\"},\"modal\":{\"noResultsText\":\"无法找到相关结果\",\"resetButtonTitle\":\"清除查询条件\",\"footer\":{\"selectText\":\"选择\",\"navigateText\":\"切换\"}}}}}}},\"logo\":\"/icon-radius.png\",\"nav\":[{\"text\":\"大前端\",\"items\":[{\"text\":\"Web前端\",\"link\":\"/largeFrontEnd/webFrontEnd/md/01.md\"},{\"text\":\"Uni-app\",\"link\":\"/largeFrontEnd/uniapp/\"},{\"text\":\"微信小程序\",\"link\":\"/largeFrontEnd/weChatMiniProgram/\"},{\"text\":\"Electron\",\"link\":\"/largeFrontEnd/electron/\"},{\"text\":\"Flutter\",\"link\":\"/largeFrontEnd/flutter/\"},{\"text\":\"前端面试题\",\"link\":\"/largeFrontEnd/interview/01.md\"}]},{\"text\":\"后端\",\"link\":\"/backEnd/\"},{\"text\":\"Linux\",\"link\":\"/linux/\"},{\"text\":\"我的团队\",\"link\":\"/myTeam/\"}],\"sidebar\":{\"/largeFrontEnd/webFrontEnd/\":[{\"text\":\"第一阶段  基础入门\",\"collapsed\":true,\"items\":[{\"text\":\"一、基础认知\",\"link\":\"/largeFrontEnd/webFrontEnd/md/01.md\"},{\"text\":\"二、HTML标签学习\",\"link\":\"/largeFrontEnd/webFrontEnd/md/02.md\"},{\"text\":\"三、HTML基础\",\"link\":\"/largeFrontEnd/webFrontEnd/md/03.md\"},{\"text\":\"四、CSS基础\",\"link\":\"/largeFrontEnd/webFrontEnd/md/04.md\"},{\"text\":\"五、CSS进阶\",\"link\":\"/largeFrontEnd/webFrontEnd/md/05.md\"},{\"text\":\"六、盒子模型\",\"link\":\"/largeFrontEnd/webFrontEnd/md/06.md\"},{\"text\":\"七、CSS浮动\",\"link\":\"/largeFrontEnd/webFrontEnd/md/07.md\"},{\"text\":\"八、CSS定位装饰\",\"link\":\"/largeFrontEnd/webFrontEnd/md/08.md\"},{\"text\":\"九、CSS精灵图\",\"link\":\"/largeFrontEnd/webFrontEnd/md/09.md\"},{\"text\":\"项目前置认知\",\"link\":\"/largeFrontEnd/webFrontEnd/md/10.md\"},{\"text\":\"项目结构搭建\",\"link\":\"/largeFrontEnd/webFrontEnd/md/11.md\"},{\"text\":\"字体图标、动画\",\"link\":\"/largeFrontEnd/webFrontEnd/md/12.md\"},{\"text\":\"移动web开发\",\"link\":\"/largeFrontEnd/webFrontEnd/md/13.md\"}]},{\"text\":\"第二阶段 技术进阶\",\"collapsed\":true,\"items\":[{\"text\":\"JavaScript深入浅出\",\"link\":\"/largeFrontEnd/webFrontEnd/md/14.md\"},{\"text\":\"JavaScript核心之web APIs\",\"link\":\"/largeFrontEnd/webFrontEnd/md/15.md\"},{\"text\":\"一、Web APIS导读\",\"link\":\"/largeFrontEnd/webFrontEnd/md/16.md\"},{\"text\":\"二、DOM导读\",\"link\":\"/largeFrontEnd/webFrontEnd/md/17.md\"},{\"text\":\"三、事件高级导读\",\"link\":\"/largeFrontEnd/webFrontEnd/md/18.md\"},{\"text\":\"四、BOM导读\",\"link\":\"/largeFrontEnd/webFrontEnd/md/19.md\"},{\"text\":\"五、PC网页特效导读\",\"link\":\"/largeFrontEnd/webFrontEnd/md/20.md\"},{\"text\":\"六、移动端特效导读\",\"link\":\"/largeFrontEnd/webFrontEnd/md/21.md\"},{\"text\":\"七、本地存储导读\",\"link\":\"/largeFrontEnd/webFrontEnd/md/22.md\"},{\"text\":\"jQuery入门导读\",\"link\":\"/largeFrontEnd/webFrontEnd/md/23.md\"},{\"text\":\"数据可视化项目导读\",\"link\":\"/largeFrontEnd/webFrontEnd/md/24.md\"}]},{\"text\":\"Node.js\",\"collapsed\":true,\"items\":[{\"text\":\"buffer(缓冲器)\",\"link\":\"/largeFrontEnd/webFrontEnd/md/25.md\"},{\"text\":\"计算机基础\",\"link\":\"/largeFrontEnd/webFrontEnd/md/26.md\"},{\"text\":\"fs模块\",\"link\":\"/largeFrontEnd/webFrontEnd/md/27.md\"},{\"text\":\"path模块\",\"link\":\"/largeFrontEnd/webFrontEnd/md/28.md\"},{\"text\":\"HTTP模块\",\"link\":\"/largeFrontEnd/webFrontEnd/md/29.md\"},{\"text\":\"Express框架\",\"link\":\"/largeFrontEnd/webFrontEnd/md/30.md\"},{\"text\":\"Mongodb\",\"link\":\"/largeFrontEnd/webFrontEnd/md/31.md\"}]},{\"text\":\"Ajax\",\"link\":\"/largeFrontEnd/webFrontEnd/md/32.md\"},{\"text\":\"前端面试题\",\"collapsed\":true,\"items\":[{\"text\":\"一、CSS\",\"link\":\"/largeFrontEnd/webFrontEnd/md/33.md\"},{\"text\":\"二、JavaScript\",\"link\":\"/largeFrontEnd/webFrontEnd/md/34.md\"},{\"text\":\"三、HTML5CSS3\",\"link\":\"/largeFrontEnd/webFrontEnd/md/35.md\"},{\"text\":\"四、Vue\",\"link\":\"/largeFrontEnd/webFrontEnd/md/36.md\"},{\"text\":\"五、Echarts\",\"link\":\"/largeFrontEnd/webFrontEnd/md/37.md\"},{\"text\":\"六.Uni-APP\",\"link\":\"/largeFrontEnd/webFrontEnd/md/38.md\"},{\"text\":\"七、webpack\",\"link\":\"/largeFrontEnd/webFrontEnd/md/39.md\"},{\"text\":\"八、Git\",\"link\":\"/largeFrontEnd/webFrontEnd/md/40.md\"}]}],\"/largeFrontEnd/flutter/\":[{\"text\":\"Flutter入门到实战\",\"collapsed\":false,\"items\":[{\"text\":\"第一章 初识Flutter\",\"link\":\"/largeFrontEnd/flutter/chapter1/index.md\"},{\"text\":\"第二章 简介\",\"link\":\"/largeFrontEnd/flutter/chapter2/index.md\"},{\"text\":\"第三章 基础组件\",\"link\":\"/largeFrontEnd/flutter/chapter3/index.md\"},{\"text\":\"第四章 布局类组件\",\"link\":\"/largeFrontEnd/flutter/chapter4/index.md\"},{\"text\":\"第五章 容器类Widget\",\"link\":\"/largeFrontEnd/flutter/chapter5/index.md\"},{\"text\":\"第六章 可滚动组件\",\"link\":\"/largeFrontEnd/flutter/chapter6/index.md\"},{\"text\":\"第七章 功能型Widget简介\",\"link\":\"/largeFrontEnd/flutter/chapter7/index.md\"},{\"text\":\"第八章 事件处理与通知\",\"link\":\"/largeFrontEnd/flutter/chapter8/index.md\"},{\"text\":\"第九章 动画\",\"link\":\"/largeFrontEnd/flutter/chapter9/index.md\"},{\"text\":\"第十章 自定义组件\",\"link\":\"/largeFrontEnd/flutter/chapter10/index.md\"},{\"text\":\"第十一章 文件操作\",\"link\":\"/largeFrontEnd/flutter/chapter11/index.md\"},{\"text\":\"第十二章 Flutter 扩展\",\"link\":\"/largeFrontEnd/flutter/chapter12/index.md\"},{\"text\":\"第十三章 多语言\",\"link\":\"/largeFrontEnd/flutter/chapter13/index.md\"},{\"text\":\"第十四章 高级进阶\",\"link\":\"/largeFrontEnd/flutter/chapter14/index.md\"}]}]},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://gitee.com/luoguangguang\"},{\"icon\":{\"svg\":\"<svg role=\\\"img\\\" viewBox=\\\"0 0 24 24\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><title>Dribbble</title><path d=\\\"M12...6.38z\\\"/></svg>\"},\"link\":\"...\",\"ariaLabel\":\"cool link\"}],\"footer\":{\"message\":\"Released under the MIT License.\",\"copyright\":\"Copyright © 2023-present LG of GZU\"},\"editLink\":{\"pattern\":\"https://gitee.com/luoguangguang/note/tree/master/docs/:path\",\"text\":\"在Gitee上参与编辑此页\"},\"carbonAds\":{\"code\":\"your-carbon-code\",\"placement\":\"your-carbon-placement\"}},\"locales\":{},\"scrollOffset\":90,\"cleanUrls\":false}");</script>
    
  </body>
</html>